<?php
class RequestHandler {

	var $gateUrl;

	var $key;

	var $parameters;

	var $debugInfo;

	function __construct() {
		$this->RequestHandler();
	}

	function RequestHandler() {
		$this->gateUrl = "https://www.tenpay.com/cgi-bin/med/show_opentrans.cgi";
		$this->key = "";
		$this->parameters = array();
		$this->debugInfo = "";
	}

	function init() {
	}

	function getGateURL() {
		return $this->gateUrl;
	}

	function setGateURL($gateUrl) {
		$this->gateUrl = $gateUrl;
	}

	function getKey() {
		return $this->key;
	}

	function setKey($key) {
		$this->key = $key;
	}

	function getParameter($parameter) {
		return $this->parameters[$parameter];
	}

	function setParameter($parameter, $parameterValue) {
		$this->parameters[$parameter] = $parameterValue;
	}

	function getAllParameters() {
		$this->createSign();

		return $this->parameters;
	}

	function getRequestURL() {
		$this->createSign();
		$reqPar = "";
		ksort($this->parameters);
		foreach($this->parameters as $k => $v) {
			$reqPar .= $k . "=" . urlencode($v) . "&";
		}

		$reqPar = substr($reqPar, 0, strlen($reqPar)-1);
		$requestURL = $this->getGateURL() . "?" . $reqPar;
		return $requestURL;

	}

	function getDebugInfo() {
		return $this->debugInfo;
	}

	function doSend() {
		header("Location:" . $this->getRequestURL());
		exit;
	}

	function createSign() {
		$signPars = "";
		ksort($this->parameters);
		foreach($this->parameters as $k => $v) {
			if("" !== $v && "sign" !== $k) {
				$signPars .= $k . "=" . $v . "&";
			}
		}
		$signPars .= "key=" . $this->getKey();
		$sign = strtolower(md5($signPars));
		$this->setParameter("sign", $sign);
		$this->_setDebugInfo($signPars . " => sign:" . $sign);

	}

	function _setDebugInfo($debugInfo) {
		$this->debugInfo = $debugInfo;
	}

}

class ResponseHandler  {

	var $key;

	var $parameters;

	var $debugInfo;

	function __construct() {
		$this->ResponseHandler();
	}

	function ResponseHandler() {
		$this->key = "";
		$this->parameters = array();
		$this->debugInfo = "";

		foreach($_GET as $k => $v) {
			$this->setParameter($k, $v);
		}
		foreach($_POST as $k => $v) {
			$this->setParameter($k, $v);
		}
	}

	function getKey() {
		return $this->key;
	}

	function setKey($key) {
		$this->key = $key;
	}

	function getParameter($parameter) {
		return $this->parameters[$parameter];
	}

	function setParameter($parameter, $parameterValue) {
		$this->parameters[$parameter] = $parameterValue;
	}

	function getAllParameters() {
		return $this->parameters;
	}

	function isTenpaySign() {
		$signPars = "";

		ksort($this->parameters);
		foreach($this->parameters as $k => $v) {
			if("sign" !== $k && "" !== $v) {
				$signPars .= $k . "=" . $v . "&";
			}
		}
		$signPars .= "key=" . $this->getKey();
		$sign = strtolower(md5($signPars));
		$tenpaySign = strtolower($this->getParameter("sign"));
		$this->_setDebugInfo($signPars . " => sign:" . $sign .
				" tenpaySign:" . $this->getParameter("sign"));

		return $sign == $tenpaySign;

	}

	function getDebugInfo() {
		return $this->debugInfo;
	}

	function _setDebugInfo($debugInfo) {
		$this->debugInfo = $debugInfo;
	}
}


class MediPayRequestHandler extends RequestHandler {

	function __construct() {
		$this->MediPayRequestHandler();
	}

	function MediPayRequestHandler() {
		$this->setGateURL("https://www.tenpay.com/cgi-bin/med/show_opentrans.cgi");
	}

	function init() {
		$this->setParameter("attach", "1");

		$this->setParameter("chnid",  "");

		$this->setParameter("cmdno", "12");

		$this->setParameter("encode_type", "1");

		$this->setParameter("mch_desc", "");

		$this->setParameter("mch_name", "");

		$this->setParameter("mch_price",  "");

		$this->setParameter("mch_returl",  "");

		$this->setParameter("mch_type",  "");

		$this->setParameter("mch_vno",  "");

		$this->setParameter("need_buyerinfo",  "");

		$this->setParameter("seller",  "");

		$this->setParameter("show_url",  "");

		$this->setParameter("transport_desc",  "");

		$this->setParameter("transport_fee",  "");

		$this->setParameter("version",  "2");

		$this->setParameter("sign",  "");

	}

}

class MediPayResponseHandler extends ResponseHandler {

	function doShow() {
		$strHtml = "<html><head>\r\n" .
			"<meta name=\"TENCENT_ONLINE_PAYMENT\" content=\"China TENCENT\">" .
			"</head><body></body></html>";

		echo $strHtml;

		exit;
	}
	function isTenpaySign() {

		$signParameterArray = array(
			'attach',
			'buyer_id',
			'cft_tid',
			'chnid',
			'cmdno',
			'mch_vno',
			'retcode',
			'seller',
			'status',
			'total_fee',
			'trade_price',
			'transport_fee',
			'version'
		);

		ksort($signParameterArray);

		foreach($signParameterArray as $k ) {
			$v = $this->getParameter($k);
			if(isset($v)) {
				$signPars .= $k . "=" . urldecode($v) . "&";
			}
		}

		$signPars .= "key=" . $this->getKey();

		$sign = strtolower(md5($signPars));

		$tenpaySign = strtolower($this->getParameter("sign"));

		$this->_setDebugInfo($signPars . " => sign:" . $sign .
				" tenpaySign:" . $this->getParameter("sign"));

		return $sign == $tenpaySign;

	}

}

class TenpayModule{
	function payurl($txn=null) {
			global $_G;
			$ecm = unserialize(decrypt($_G['settings']['payment']['tenpay']));
			$subject = $_G['settings']['sitename'];
			
			$reqHandler = new RequestHandler();
			$reqHandler->setGateURL("https://gw.tenpay.com/gateway/pay.htm");
			$reqHandler->init();
			$reqHandler->setKey($ecm['tkey']);
		
			$reqHandler->setParameter("partner", $ecm['tbargaino']);
			$reqHandler->setParameter("out_trade_no", $txn['txnid']);
			$reqHandler->setParameter("total_fee", $txn['gross'] * 100);
			$reqHandler->setParameter("return_url", BASE_URL.'payment.php?f=result&type=tenpay');
			$reqHandler->setParameter("notify_url", BASE_URL.'payment.php?f=notify&type=tenpay');
			$reqHandler->setParameter("body", $subject);
			$reqHandler->setParameter("bank_type", 'DEFAULT');//银行
		
			$reqHandler->setParameter("spbill_create_ip", $_G['ip']);
			$reqHandler->setParameter("fee_type", "1");
			$reqHandler->setParameter("subject", $subject);
		
			$reqHandler->setParameter("sign_type", "MD5");
			$reqHandler->setParameter("service_version", "1.0");
			$reqHandler->setParameter("input_charset", CHARSET);
			$reqHandler->setParameter("sign_key_index", "1");
		
			$reqHandler->setParameter("attach", "tenpay");
			$reqHandler->setParameter("time_start", gdate("YmdHis"));
			$reqHandler->setParameter("trade_mode","1");//交易模式（1.即时到帐模式，2.中介担保模式，3.后台选择（卖家进入支付中心列表选择））
			$reqHandler->setParameter("trans_type","1");
			$reqHandler->setParameter("agentid", '1204737401');
			$reqHandler->setParameter("agent_type","2");
		
			$reqUrl = $reqHandler->getRequestURL();
			return $reqUrl;
	}
	
	function notify($type) {
		global $_G;
		$ecm = unserialize(decrypt($_G['settings']['payment']['tenpay']));
		
		//只有签名正确,retcode为0，trade_state为0才是支付成功
		if($_GET['trade_mode']=="1"){//即时交易
			$resHandler = new ResponseHandler();
			$resHandler->setKey($ecm['tkey']);
			$resHandler->setParameter("bankname", "");
			
			if($resHandler->isTenpaySign() && $ecm['tbargaino'] == $_GET['partner']) {
				return array(
					'check'	=> true,
					'txnid' 	=> $_GET['out_trade_no'],
					'trade_no'	=> isset($_GET['transaction_id']) ? $_GET['transaction_id'] : '',
					'price' 	=> $_GET['total_fee'] / 100,
					'status' => isset($_GET['trade_state']) ? !$_GET['trade_state'] : 0,
					'notify'	=> 'success',
					);
			}else{
				return array(
					'check'	=> false,
					'txnid' 	=> $_GET['out_trade_no'],
					'trade_no'	=> isset($_GET['transaction_id']) ? $_GET['transaction_id'] : '',
					'price' 	=> $_GET['total_fee'] / 100,
					'status' => isset($_GET['trade_state']) ? !$_GET['trade_state'] : 0,
					'notify'	=> 'fail',
					);
			}
			
		}else if($_GET['trade_mode']=="2"){//担保交易
			$resHandler = new MediPayResponseHandler();
			$resHandler->setKey($ecm['tcode']);
			
			if($resHandler->isTenpaySign() && $resHandler->getParameter('retcode') == "0") {
				return array(
					'check' => true,
					'txnid' => $resHandler->getParameter('mch_vno'),
					'trade_no' => $resHandler->getParameter('cft_tid'),
					'price' => $resHandler->getParameter('total_fee') / 100,
					'status' => $resHandler->getParameter("trade_state")=="0",
					'notify'	=> 'success',
				);
			}else{
				return array(
					'check' => false,
					'txnid' => $resHandler->getParameter('mch_vno'),
					'trade_no' => $resHandler->getParameter('cft_tid'),
					'price' => $resHandler->getParameter('total_fee') / 100,
					'status' => $resHandler->getParameter("trade_state")=="0",// $resHandler->getParameter('trade_state'),
					'notify'	=> 'fail',
				);
			}
		}else{
			return array(
					'check' => false,
					'notify'	=> 'fail',
				);
		}
		
	}

	function trade_getorderurl($orderid) {
		return "https://www.tenpay.com/med/tradeDetail.shtml?b=1&trans_id=$orderid";
	}
	
}